#ifndef IDDATABASE_H
#define IDDATABASE_H

#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <mutex>
#include <atomic>
#include <sqlite3.h>
#include <type_traits> // for std::is_pod and std::is_same
#include <chrono>
#include <ctime>
#include <algorithm> // 包含 std::reverse

template <typename T>
class IdDatabase
{
public:
    // 初始化数据库
    IdDatabase(const std::string &filename)
        : filename_(filename)
    {
        static_assert(std::is_pod<T>::value, "Record type must be POD");

        // 打开或创建数据库
        int rc = sqlite3_open(filename_.c_str(), &db_);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to open database");
        }

        // 创建表
        const char *sql = "CREATE TABLE IF NOT EXISTS persons ("
                          "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                          "person_id TEXT, "
                          "data BLOB);";
        char *zErrMsg = nullptr;
        rc = sqlite3_exec(db_, sql, nullptr, nullptr, &zErrMsg);
        if (rc != SQLITE_OK)
        {
            sqlite3_free(zErrMsg);
            throw std::runtime_error("Failed to create table");
        }
    }

    ~IdDatabase()
    {
        sqlite3_close(db_);
    }

    // 注册人员（线程安全）
    void RegisterPerson(const std::string &person_id, const T &data)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        // 插入记录
        const char *sql = "INSERT INTO persons (person_id, data) VALUES (?, ?);";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        sqlite3_bind_text(stmt, 1, person_id.c_str(), -1, SQLITE_STATIC);
        sqlite3_bind_blob(stmt, 2, &data, sizeof(T), SQLITE_STATIC);

        rc = sqlite3_step(stmt);
        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to insert record");
        }

        sqlite3_finalize(stmt);
    }

    // 查找人员（线程安全）
    std::vector<T> FindPerson(const std::string &person_id) const
    {
        std::lock_guard<std::mutex> lock(mutex_);

        const char *sql = "SELECT data FROM persons WHERE person_id = ?;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        sqlite3_bind_text(stmt, 1, person_id.c_str(), -1, SQLITE_STATIC);

        std::vector<T> result;
        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
        {
            const void *data = sqlite3_column_blob(stmt, 0);
            result.emplace_back(*static_cast<const T *>(data));
        }

        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read records");
        }

        sqlite3_finalize(stmt);

        return result;
    }

    // 删除人员（线程安全）
    void DeletePerson(const std::string &person_id)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        const char *sql = "DELETE FROM persons WHERE person_id = ?;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        sqlite3_bind_text(stmt, 1, person_id.c_str(), -1, SQLITE_STATIC);

        rc = sqlite3_step(stmt);
        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to delete record");
        }

        sqlite3_finalize(stmt);
    }

    // 获取所有人员信息（线程安全）
    std::vector<std::pair<std::string, T>> GetAllPersons() const
    {
        std::lock_guard<std::mutex> lock(mutex_);

        const char *sql = "SELECT person_id, data FROM persons;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        std::vector<std::pair<std::string, T>> result;
        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
        {
            const char *person_id = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
            const void *data = sqlite3_column_blob(stmt, 1);
            result.emplace_back(person_id, *static_cast<const T *>(data));
        }

        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read records");
        }

        sqlite3_finalize(stmt);

        return result;
    }

    // 获取数据库条数（公共方法，线程安全）
    size_t GetRecordCount() const
    {
        std::lock_guard<std::mutex> lock(mutex_);
        return GetRecordCountImpl();
    }

    // 删除所有记录（公共方法，线程安全）
    void DeleteAllRecords()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        DeleteAllRecordsImpl();
    }

private:
    // 获取数据库条数（私有方法）
    size_t GetRecordCountImpl() const
    {
        const char *sql = "SELECT COUNT(*) FROM persons;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        size_t count = 0;
        if (sqlite3_step(stmt) == SQLITE_ROW)
        {
            count = sqlite3_column_int(stmt, 0);
        }

        if (sqlite3_step(stmt) != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to read record count");
        }

        sqlite3_finalize(stmt);

        return count;
    }

    // 删除所有记录（私有方法）
    void DeleteAllRecordsImpl()
    {
        const char *sql = "DELETE FROM persons;";
        sqlite3_stmt *stmt;
        int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK)
        {
            throw std::runtime_error("Failed to prepare statement");
        }

        rc = sqlite3_step(stmt);
        if (rc != SQLITE_DONE)
        {
            sqlite3_finalize(stmt);
            throw std::runtime_error("Failed to delete all records");
        }

        sqlite3_finalize(stmt);
    }

private:
    sqlite3 *db_ = nullptr; // SQLite 数据库连接
    std::string filename_;     // 文件名
    mutable std::mutex mutex_; // 普通互斥锁
};

#endif // IDDATABASE_H